{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from keras.layers import Input, concatenate, Embedding, Dropout\n",
    "from keras.layers.core import Dense, Activation, Flatten\n",
    "from keras.models import Model\n",
    "from keras.utils import plot_model\n",
    "from keras import backend as K"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 定义f1指标"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def f1(y_true, y_pred):\n",
    "\tdef recall(y_true, y_pred):\n",
    "\t\ttrue_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n",
    "\t\tpossible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))\n",
    "\t\trecall = true_positives / (possible_positives + K.epsilon())\n",
    "\n",
    "\t\treturn recall\n",
    "\n",
    "\tdef precision(y_true, y_pred):\n",
    "\t\ttrue_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n",
    "\t\tpredicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))\n",
    "\t\tprecision = true_positives / (predicted_positives + K.epsilon())\n",
    "\n",
    "\t\treturn precision\n",
    "\n",
    "\tprecision = precision(y_true, y_pred)\n",
    "\trecall = recall(y_true, y_pred)\n",
    "\n",
    "\treturn 2 * ((precision*recall) / (precision + recall + K.epsilon()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 构建模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def model(LOSS, OPT, dropout_ALPHA):\n",
    "\t# 计算f1指标\n",
    "\tdef f1(y_true, y_pred):\n",
    "\t\tdef recall(y_true, y_pred):\n",
    "\t\t\ttrue_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n",
    "\t\t\tpossible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))\n",
    "\t\t\trecall = true_positives / (possible_positives + K.epsilon())\n",
    "\n",
    "\t\t\treturn recall\n",
    "\n",
    "\t\tdef precision(y_true, y_pred):\n",
    "\t\t\ttrue_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n",
    "\t\t\tpredicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))\n",
    "\t\t\tprecision = true_positives / (predicted_positives + K.epsilon())\n",
    "\n",
    "\t\t\treturn precision\n",
    "\n",
    "\t\tprecision = precision(y_true, y_pred)\n",
    "\t\trecall = recall(y_true, y_pred)\n",
    "\n",
    "\t\treturn 2 * ((precision*recall) / (precision + recall + K.epsilon()))\n",
    "\n",
    "\tdef res_block(x, layer_size):\n",
    "\t\tdrop1 = Dropout(dropout_ALPHA)(x)\n",
    "\t\tden1 = Dense(layer_size)(drop1)\n",
    "\t\tbatch1 = BatchNormalization(epsilon=0.00001)(den1)\n",
    "\t\trel1 = Activation('relu')(batch1)\n",
    "\n",
    "\t\tdrop2 = Dropout(dropout_ALPHA - 0.1)(rel1)\n",
    "\t\tden2 = Dense(layer_size)(drop2)\n",
    "\t\tbatch2 = BatchNormalization(epsilon=0.00001)(den2)\n",
    "\n",
    "\t\treturn add([x, batch2])\n",
    "\n",
    "\t# 多输入\n",
    "\tinput1 = Input(shape=(114,))\n",
    "\tinput2 = Input(shape=(10,))\n",
    "\n",
    "\t# 分支部分\n",
    "\tdense1 = Dense(64)(input1)\n",
    "\tactive1 = Activation('relu')(dense1)\n",
    "\tembedding = Embedding(18375, 512, input_length=(10,))(input2)\n",
    "\tflatten = Flatten()(embedding)\n",
    "\n",
    "\t# 合并\n",
    "\tmerge = concatenate([active1, flatten])\n",
    "\n",
    "\tdropout1 = Dropout(dropout_ALPHA)(merge)\n",
    "\tdense2 = Dense(4096)(dropout1)\n",
    "\tactive2 = Activation('relu')(dense2)\n",
    "\n",
    "\tres1 = res_block(active2, 4096)\n",
    "\tactive3 = Activation('relu')(res1)\n",
    "\n",
    "\tdropout2 = Dropout(dropout_ALPHA)(active3)\n",
    "\tdense3 = Dense(2048)(dropout2)\n",
    "\tactive4 = Activation('relu')(dense3)\n",
    "\n",
    "\tres2 = res_block(active4, 2048)\n",
    "\tactive5 = Activation('relu')(res2)\n",
    "\n",
    "\tdropout3 = Dropout(dropout_ALPHA)(active5)\n",
    "\tdense4 = Dense(1024)(dropout3)\n",
    "\tactive6 = Activation('relu')(dense4)\n",
    "\n",
    "\tres3 = res_block(active6, 1024)\n",
    "\tactive7 = Activation('relu')(res3)\n",
    "\n",
    "\tdropout4 = Dropout(dropout_ALPHA)(active7)\n",
    "\tdense5 = Dense(512)(dropout4)\n",
    "\tactive8 = Activation('relu')(dense5)\n",
    "\n",
    "\tres4 = res_block(active8, 512)\n",
    "\tactive9 = Activation('relu')(res4)\n",
    "\n",
    "\tdropout5 = Dropout(dropout_ALPHA)(active9)\n",
    "\tdense6 = Dense(256)(dropout5)\n",
    "\tactive10 = Activation('relu')(dense6)\n",
    "\n",
    "\tres5 = res_block(active10, 256)\n",
    "\tactive11 = Activation('relu')(res5)\n",
    "\n",
    "\tdropout6 = Dropout(dropout_ALPHA)(active11)\n",
    "\tdense7 = Dense(1)(dropout6)\n",
    "\tactive12 = Activation('sigmoid')(dense7)\n",
    "\n",
    "\tmodel = Model(inputs=[input1,input2], outputs=active12)\n",
    "\tmodel.compile(loss=LOSS, metrics=[f1], optimizer=OPT)\n",
    "\n",
    "\treturn model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = model(\"binary_crossentropy\", \"adam\", 0.5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "__________________________________________________________________________________________________\n",
      "Layer (type)                    Output Shape         Param #     Connected to                     \n",
      "==================================================================================================\n",
      "input_7 (InputLayer)            (None, 114)          0                                            \n",
      "__________________________________________________________________________________________________\n",
      "input_8 (InputLayer)            (None, 10)           0                                            \n",
      "__________________________________________________________________________________________________\n",
      "dense_43 (Dense)                (None, 64)           7360        input_7[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "embedding_4 (Embedding)         (None, 10, 512)      9408000     input_8[0][0]                    \n",
      "__________________________________________________________________________________________________\n",
      "activation_43 (Activation)      (None, 64)           0           dense_43[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "flatten_4 (Flatten)             (None, 5120)         0           embedding_4[0][0]                \n",
      "__________________________________________________________________________________________________\n",
      "concatenate_4 (Concatenate)     (None, 5184)         0           activation_43[0][0]              \n",
      "                                                                 flatten_4[0][0]                  \n",
      "__________________________________________________________________________________________________\n",
      "dropout_39 (Dropout)            (None, 5184)         0           concatenate_4[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_44 (Dense)                (None, 4096)         21237760    dropout_39[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_44 (Activation)      (None, 4096)         0           dense_44[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_40 (Dropout)            (None, 4096)         0           activation_44[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_45 (Dense)                (None, 4096)         16781312    dropout_40[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_45 (Activation)      (None, 4096)         0           dense_45[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_41 (Dropout)            (None, 4096)         0           activation_45[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_46 (Dense)                (None, 4096)         16781312    dropout_41[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_46 (Activation)      (None, 4096)         0           dense_46[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_42 (Dropout)            (None, 4096)         0           activation_46[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_47 (Dense)                (None, 2048)         8390656     dropout_42[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_47 (Activation)      (None, 2048)         0           dense_47[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_43 (Dropout)            (None, 2048)         0           activation_47[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_48 (Dense)                (None, 2048)         4196352     dropout_43[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_48 (Activation)      (None, 2048)         0           dense_48[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_44 (Dropout)            (None, 2048)         0           activation_48[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_49 (Dense)                (None, 2048)         4196352     dropout_44[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_49 (Activation)      (None, 2048)         0           dense_49[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_45 (Dropout)            (None, 2048)         0           activation_49[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_50 (Dense)                (None, 1024)         2098176     dropout_45[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_50 (Activation)      (None, 1024)         0           dense_50[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_46 (Dropout)            (None, 1024)         0           activation_50[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_51 (Dense)                (None, 1024)         1049600     dropout_46[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_51 (Activation)      (None, 1024)         0           dense_51[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_47 (Dropout)            (None, 1024)         0           activation_51[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_52 (Dense)                (None, 1024)         1049600     dropout_47[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_52 (Activation)      (None, 1024)         0           dense_52[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_48 (Dropout)            (None, 1024)         0           activation_52[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_53 (Dense)                (None, 512)          524800      dropout_48[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_53 (Activation)      (None, 512)          0           dense_53[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dense_54 (Dense)                (None, 512)          262656      activation_53[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "activation_54 (Activation)      (None, 512)          0           dense_54[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_50 (Dropout)            (None, 512)          0           activation_54[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_55 (Dense)                (None, 512)          262656      dropout_50[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_55 (Activation)      (None, 512)          0           dense_55[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_51 (Dropout)            (None, 512)          0           activation_55[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_56 (Dense)                (None, 256)          131328      dropout_51[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_56 (Activation)      (None, 256)          0           dense_56[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_52 (Dropout)            (None, 256)          0           activation_56[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_57 (Dense)                (None, 256)          65792       dropout_52[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_57 (Activation)      (None, 256)          0           dense_57[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_53 (Dropout)            (None, 256)          0           activation_57[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_58 (Dense)                (None, 256)          65792       dropout_53[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_58 (Activation)      (None, 256)          0           dense_58[0][0]                   \n",
      "__________________________________________________________________________________________________\n",
      "dropout_54 (Dropout)            (None, 256)          0           activation_58[0][0]              \n",
      "__________________________________________________________________________________________________\n",
      "dense_59 (Dense)                (None, 1)            257         dropout_54[0][0]                 \n",
      "__________________________________________________________________________________________________\n",
      "activation_59 (Activation)      (None, 1)            0           dense_59[0][0]                   \n",
      "==================================================================================================\n",
      "Total params: 86,509,761\n",
      "Trainable params: 86,509,761\n",
      "Non-trainable params: 0\n",
      "__________________________________________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_model(model, to_file='model1.png',show_shapes=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
